use std::path::Path;
use std::result::Result::Ok;
use std::sync::Arc;

use anyhow::{Context, Result};
use arc_swap::ArcSwap;
use once_cell::sync::Lazy;
use serde_derive::{Deserialize, Serialize};

const CFG_FILE: &str = "config.toml";

pub(crate) static CONFIG: Lazy<ArcSwap<Config>> = Lazy::new(|| {
    let cfg = smol::block_on(read_config()).expect("初始化配置信息失败");
    ArcSwap::from_pointee(cfg)
});

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub(crate) struct Config {
    pub(crate) own: Own,
    pub(crate) provider: Provider,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub(crate) struct Own {
    pub(crate) addr: String,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub(crate) struct Provider {
    pub(crate) addr: String,
}

pub(crate) async fn reload() {
    if let Ok(cfg) = read_config().await {
        CONFIG.store(Arc::new(cfg))
    }
}

async fn read_config() -> Result<Config> {
    if !Path::new(CFG_FILE).exists() {
        let cfg: Config = Config {
            own: Own {
                addr: "127.0.0.1:9000".to_string(),
            },
            provider: Provider {
                addr: "127.0.0.1:20888".to_string(),
            },
        };
        smol::fs::write(CFG_FILE, toml::to_string_pretty(&cfg)?).await?
    }

    let res = smol::fs::read_to_string(CFG_FILE).await?;
    toml::from_str::<Config>(&*res).context("解析配置文件失败")
}
